<?php
/**
 * Created by PhpStorm.
 * User: ari
 * Date: 10/20/14
 * Time: 11:23 PM
 */
namespace BC\Render;

use BC\PGP\PGPSupportHeaders;
use BC\SiteIndex;
use BC\User\Session\UserSession;
use BC\User\UserConfig;
use BC\User\UserUIContainer;
use CPath\Build\IBuildable;
use CPath\Build\IBuildRequest;
use CPath\Render\HTML\AbstractHTMLContainer;
use CPath\Render\HTML\Common\HTMLText;
use CPath\Render\HTML\Element\HTMLElement;
use CPath\Render\HTML\Header\HTMLMetaTag;
use CPath\Render\HTML\HTMLContainer;
use CPath\Render\HTML\HTMLMimeType;
use CPath\Render\HTML\HTMLResponseBody;
use CPath\Render\HTML\IRenderHTML;
use CPath\Request\IRequest;
use CPath\Request\Session\ISessionRequest;
use CPath\Response\IResponse;
use CPath\Response\IResponseHeaders;
use CPath\Response\ResponseRenderer;
use CPath\Route\HTML\HTMLRouteNavigator;
use CPath\Route\IRoutable;
use CPath\Route\RouteBuilder;

class DefaultTemplate extends HTMLContainer implements IRoutable, IBuildable
{
	const CLS_CONSOLE = 'console';
//
//	const META_TITLE = 'title';
//	const META_AUTHOR = 'author';
//	const META_DESCRIPTION = 'description';

	const META_PATH = 'path';
	const META_SESSION = 'session';
	const META_SESSION_ID = 'session-id';
	const META_DOMAIN_PATH = 'domain-path';

	/** @var AbstractHTMLContainer  */
	protected $Render, $Header, $HeaderTitle, $Console, $Footer, $NavBar, $NavBarTitle, $Content;
	private $mUIContainer;
	private $mLogElement;
	public function __construct($_content=null) {

		$this->Render = new HTMLResponseBody(
			$this->Header = new HTMLElement('section', 'header',
				$this->HeaderTitle = new HTMLElement('h1', 'header-title')
			),
			$this->NavBar = new HTMLElement('section', 'navbar',
				$this->NavBarTitle = new HTMLElement('h3', 'navbar-title'),
				new HTMLRouteNavigator(new SiteIndex)
			),
			$this->Content = new HTMLElement('section', 'content'
				// new HTMLElement('h2', 'content-title', basename(get_class($_content)))
			),
			$this->Footer = new HTMLElement('section', 'footer',
				$this->mLogElement = new HTMLElement('div', self::CLS_CONSOLE)
			),
			//$this->Console = new HTMLConsole()
			$this->mUIContainer = new UserUIContainer()
		);

		parent::__construct($this->Render);
		$this->setContainer($this->Content);

		//$this->Console->getHTMLLog()->bindEventListener('body');
		$this->addAll(func_get_args());

		$this->Render->addSupportHeaders($this);
		$this->addSupportHeaders(new UserConfig());
		$this->addHeaderScript(__DIR__ . '/assets/default-template.js');
		$this->addHeaderStyleSheet(__DIR__ . '/assets/default-template.css');
		$this->addSupportHeaders(
			//new HTMLAjaxSupportHeaders(),
			new PGPSupportHeaders()
		);
	}

	public function setTitle($title) {
		$this->HeaderTitle->removeContent();
		$this->HeaderTitle->addContent(new HTMLText($title));
		$this->Render->setHeaderTitle($title);
	}

	public function setPath($path) {
		$this->NavBar->removeContent();
		$this->NavBar->addContent(new HTMLElement('h3', 'navbar-title', $path));
		$this->NavBar->addContent(new HTMLRouteNavigator(new SiteIndex, 1, $path));
	}


	// Static

	/**
	 * Handle this request and render any content
	 * @param IBuildRequest $Request the build request inst for this build session
	 * @return void
	 * @build --disable 0
	 * Note: Use doctag 'build' with '--disable 1' to have this IBuildable class skipped during a build
	 */
	static function handleBuildStatic(IBuildRequest $Request) {
		$RouteBuilder = new RouteBuilder($Request, new SiteIndex());
		$RouteBuilder->writeRoute('ANY *', __CLASS__);
	}

	/**
	 * Route the request to this class object and return the object
	 * @param IRequest $Request the IRequest inst for this render
	 * @param Object[]|null $Previous all previous response object that were passed from a handler, if any
	 * @param null|mixed $_arg [varargs] passed by route map
	 * @return void|bool|Object returns a response object
	 * If nothing is returned (or bool[true]), it is assumed that rendering has occurred and the request ends
	 * If false is returned, this static handler will be called again if another handler returns an object
	 * If an object is returned, it is passed along to the next handler
	 */
	static function routeRequestStatic(IRequest $Request, Array &$Previous = array(), $_arg = null) {
		if(sizeof($Previous) > 0) {
			$Object = reset($Previous);

			if($Request->getMimeType() instanceof HTMLMimeType) {

				$Renderer = null;
				if($Object instanceof IRenderHTML)
					$Renderer = $Object;

				if($Renderer) {

					if ($Object instanceof IResponseHeaders) {
						$Object->sendHeaders($Request);

					} else if ($Object instanceof IResponse) {
						$ResponseRenderer = new ResponseRenderer($Object);
						$ResponseRenderer->sendHeaders($Request);
					}

					header('Cache-Control: private, max-age=0, no-cache, must-revalidate, no-store, proxy-revalidate');
					header('X-Location: ' . $_SERVER['REQUEST_URI']);


					$Template = new DefaultTemplate();
					$Template->setTitle($Request->getMethodName() . ' ' . $Request->getPath());
					$Template->setPath($Request->getPath());

					$Template->addMetaTag(HTMLMetaTag::META_CONTENT_TYPE, 'text/html; charset=utf-8');
					$Template->addMetaTag(self::META_PATH, $Request->getPath());
					$Template->addMetaTag(self::META_DOMAIN_PATH, $Request->getDomainPath(false));

					if ($Request instanceof ISessionRequest && UserSession::hasSession($Request)) {
						$UserSession = UserSession::fromSession($Request);
//						$Template->addMetaTag(self::META_USER, $User->getFingerprint());
//						$Template->addMetaTag(self::META_USER_ID, $UserSession->getPGPInfo($Request)->getUserID());
						$Template->addMetaTag(self::META_SESSION_ID, $UserSession::getSessionIDFromSession($Request));
						$Template->addMetaTag(self::META_SESSION, $UserSession->getGrantFingerprint());
					}

					$Template->addContent($Renderer);
					for($i=1; $i<sizeof($Previous); $i++)
						$Template->addAll($Previous[$i]);

//					$TagReader = new HeaderTagReader();
//					$Template->writeHeaders($Request, $TagReader);
//					if($TagReader->hasTag(self::META_TITLE))
//						$Template->setTitle($TagReader->getTag(self::META_TITLE));

					$Template->renderHTML($Request);

					return true;
				}
			}
		}

		return false;
	}
}